#include "widget.h"
#include <QApplication>
#include <sys/stat.h> // fifo
#include <sys/types.h>  // fifo
#include <sys/wait.h>
#include <fcntl.h> // open
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h> // share mem
#include <sys/shm.h> // share mem
#include<QDebug>
#include <iostream>

// save fork pid to
typedef struct shmpid{
    int pid_1;
    int pid_2;
}PID;

int main(int argc, char *argv[])
{

    // nonname pipe
    int pipe_fds[2];
    int fifo_fd;
    pid_t pid;
    int i ;

    key_t pids_key;
    if( (pids_key = ftok("/" , 2)) == -1  )
    {
        perror("fail to ftok");
    }


    // create shm
    int shmid;
    if( (shmid = shmget(pids_key , 500 , IPC_CREAT|0777 ) ) ==-1 )
    {
        perror("perror to shmget");
    }

    // shmat
    PID * pids_addr;
    if(  (pids_addr =   (PID *)shmat(shmid, NULL , 0) ) == (PID *) -1 )
    {
        perror("fail to shmat");
    }







    // 1. create pipe for parent and son process
    if(pipe(pipe_fds) == -1)
    {
        std::cout << "create pipe failed" << std::endl;
    }

    // 2. create fifo , remove it before
    unlink("./player_fifo");

    // 3. when process running ,makefifo
    int mkfifo_ret = mkfifo("./player_fifo" , 0666 );

    if(mkfifo_ret < 0 )
    {
        perror("mkfifo error");
    }

    // 4. open fd using this created fifo
    fifo_fd = open("./player_fifo",O_RDWR );

    if(fifo_fd < 0)
    {
        perror("open error");
    }

// -----------------------------------------------------------

    // 5. create two child processs to exec mplayer

    for( i = 0 ; i < 2 ; i++ )
    {
        pid = fork();
        if(pid == 0)
        {
            break;
        }
    }


    if ( i == 0 ) // son process is to execp mplayer
    {
        // make system output bind to pipe_fds[1]
        dup2(pipe_fds[1] , 1);

        // shm mem to put mplayer pid
        pids_addr->pid_1 = getpid();

        qDebug()<< "mplayer exec pid = " << getpid();

        execlp("mplayer","mplayer","-slave","-idle", "-quiet", "-input","file=./player_fifo",NULL);


    }else if ( i == 1)
    {

        QApplication a(argc, argv);
        pids_addr->pid_2 = getpid();
        Widget w(pipe_fds[0]);
        w.show();
        return a.exec();


    }else if(i == 2)
    {
        int ret;
        // father process is take charge of recovery of resources
        while( 1 )
        {
            ret = waitpid(-1 , NULL , WNOHANG);

            if(ret == 0 )
            {
//                qDebug()<< "still child process running!";
                sleep(1);
                continue;
            }else if( ret > 0)
            {
                // wait a son finished
               qDebug() << "son process: " << ret   << " is finished !" ;
               if(ret == pids_addr->pid_2)
               {
                   kill(pids_addr->pid_1 , 9);
               }
            }else if( ret < 0)
            {
                close(pipe_fds[0]);
                close(pipe_fds[1]);
                close(fifo_fd);
                exit(0);
                break;

            }
        }

    }






}
